#!/usr/bin/env python3.11
# -*- encoding: utf-8 -*-
"""
@File    :   models.py
@Time    :   2024/05/27 17:13:30
@Author  :   windstarry 
@Version :   1.0
"""
# here put the import lib
import uuid

from django.conf import settings
from django.db import models
from django.utils.translation import gettext_lazy as _


class DbUuidModel(models.Model):
    """
    一个基于Django ORM的模型类，用于生成具有UUID作为主键的模型基类。
    
    属性:
        id (models.UUIDField): 作为模型主键的UUID字段， 默认使用uuid.uuid4生成一个随机UUID。
    """

    # 使用UUID作为主键的模型字段定义
    id = models.UUIDField(default=uuid.uuid4, primary_key=True, verbose_name="主键ID")

    class Meta:
        """
        元信息类，用于定义模型的一些行为特征。
        
        属性:
            abstract (bool): 指定该模型类是一个抽象基类，不会直接创建数据库表。
        """
        abstract = True  # 将该模型定义为抽象基类，不会直接在数据库中创建对应的表


class DbCharModel(models.Model):
    """
    DbCharModel是一个抽象基类，定义了一个使用CharField作为主键的模型。

    属性:
        id: 用作主键的字符字段，最大长度为128个字符。
    """
    
    id = models.CharField(primary_key=True, max_length=128, verbose_name="主键ID")

    class Meta:
        """
        Meta内部类指定了DbCharModel的一些行为特性。

        属性:
            abstract: 设置为True表示DbCharModel是一个抽象基类，不会创建对应的数据库表。
        """
        abstract = True


class DbBaseModel(models.Model):
    """
    DbBaseModel 是一个抽象基类，用于定义模型的基本属性。

    属性:
    - created_time: 记录的创建时间，自动设置为当前时间。
    - updated_time: 记录的最后更新时间，每次保存模型时自动设置为当前时间。
    - desc: 记录的描述信息，可选字段。
    - sort: 记录的显示排序，一个整数，默认为1，可选字段。
    """

    # 创建时间和更新时间字段，自动管理生命周期
    created_time = models.DateTimeField(auto_now_add=True, verbose_name="添加时间")
    updated_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    
    # 描述信息字段，可为空，用于提供额外的信息
    desc = models.CharField(
        max_length=256, verbose_name="描述信息", null=True, blank=True
    )
    
    # 记录的显示排序字段，可选，用于前端显示的顺序
    sort = models.IntegerField(
        default=1, null=True, blank=True, verbose_name="显示排序", help_text="显示排序"
    )

    class Meta:
        """
        Meta 类用于提供额外的模型元数据。
        
        属性:
        - abstract: 设置为True表示这是一个抽象基类。
        - verbose_name: 用于管理模型的可读名。
        - verbose_name_plural: 管理模型复数形式的可读名。
        """
        # 指定模型为抽象基类
        abstract = True
        # 管理模型的单数和复数形式的可读名
        verbose_name = "核心模型"
        verbose_name_plural = verbose_name


class DbAuditModel(DbBaseModel):
    """
    定义一个数据库审计模型，作为一个基类，用于其他模型的继承。

    属性:
        creator (ForeignKey): 表示创建该记录的用户，是一个外键关系，可以为空，当关联的用户被删除时，该字段会被设置为NULL。
        modifier (ForeignKey): 表示最后修改该记录的用户，同样是一个外键关系，可以为空，处理方式同creator字段。
    """

    # 创建人字段，使用ForeignKey与用户模型关联，允许为空，当关联的用户被删除时，设为NULL
    creator = models.ForeignKey(
        to=settings.AUTH_USER_MODEL,
        related_query_name="creator_query",
        null=True,
        blank=True,
        verbose_name="创建人",
        on_delete=models.SET_NULL,
        related_name="+",
    )
    
    # 修改人字段，与creator字段类似，用于记录最后修改记录的用户
    modifier = models.ForeignKey(
        to=settings.AUTH_USER_MODEL,
        related_query_name="modifier_query",
        null=True,
        blank=True,
        verbose_name="修改人",
        on_delete=models.SET_NULL,
        related_name="+",
    )

    class Meta:
        """
        元信息类，定义了该模型是一个抽象基类。
        
        属性:
            abstract (bool): 指定该模型是一个抽象基类，不会直接创建对应的数据库表。
        """
        abstract = True  # 指定该模型为抽象基类


class ModeTypeAbstract(models.Model):
    """
    数据权限模式抽象类，定义了数据权限的两种模式：或模式和且模式。

    属性:
        mode_type: 数据权限模式字段，是一个SmallIntegerField，可选值为ModeChoices中的OR或AND，默认为OR。
    """

    class ModeChoices(models.IntegerChoices):
        """
        定义数据权限模式的枚举类，提供可选的模式值及其显示名称。
        """
        OR = 0, _("或模式")  # 表示或逻辑模式
        AND = 1, _("且模式")  # 表示且逻辑模式

    mode_type = models.SmallIntegerField(choices=ModeChoices, default=ModeChoices.OR, verbose_name="数据权限模式")

    class Meta:
        """
        Meta类用于定义模型的元数据选项。
        
        属性:
            abstract: 设置为True表示这是一个抽象基类，其字段将被其派生类继承。
        """
        abstract = True





